<?
class Module extends Root{
	var $Nom;												//Nom du Module
	var $Data;
	var $StorProc;
	var $Droits = Array();
	var $DataSource;
// 	var $Comment;
	var $Title;
	var $Schema;								//Le schema sous forme de tableau
	var $SchemaLoaded = false;						//Savoir si le schema est charge ou pas
	var $Db;								//Objet contenant le schema charg�
	var $Cache=true;
	var $Bdd;
	var $TriggerFile = ""; //String
	var $Triggers;
	var $Functions = Array();

	function Module ($Tab) {						//Constructeur du Module
		$this->Cache=true;
		//Configuration du module
		$this->Nom=$Tab["NAME"];
		$this->Title= $Tab["TITLE"];
		$this->Schema= $Tab["SCHEMA"]["SCHEMA"]["#"];
		$this->Description= $Tab["COMMENT"];
		$this->TriggerFile=$Tab["TRIGGER"];
		$this->Nom=$Tab["NAME"];
		$this->Bdd=$Tab["BDD"];
//		print_r($Tab);
		$Functions = $Tab["FUNCTIONS"]["FUNCTION"];
		//On place les fonctions dans lordre
		if (!is_array($this->Functions[0])&&$Functions["TITRE"]!=""){
			$this->Functions[0] = $Functions;
		}elseif ($Functions[0]["TITRE"]!=""){
			$this->Functions = $Functions;
		}
		//DEBUG
		define("DEBUG_MODULE",0);
	}

	function init() {
	}


	function Affich($Lien,$Process) {
		$Bloc=$this->setData($Lien);
// 		print_r($Bloc);
		//Definition des variables
		$T =$Bloc->Conf;
		if (sizeof($T))foreach ($T as $K=>$V){
			$V = $Process->processingVars($V);
			$Process->RegisterTempVar($K,$V);
		}
		$GLOBALS["Systeme"]->Log->log("START GENERATE LEVEL");
		$Bloc->Generate($Process);
		$GLOBALS["Systeme"]->Log->log("END GENERATE LEVEL");
// 		die();
		$Result = $Bloc->Affich();
		return $Result;
	}

	function writeCacheFile($Data,$Url,$Name) {
		if (!$File=@fopen ($Url.$Name,"w")){
			$this->mk_dir($Url);
			if (!$File=fopen ($Url.$Name,"w")) return false;
		}
		fwrite($File,$Data);
		fclose($File);
	}

	function getDataSource($Type,$Id) {
		//Construction de l arbres des donn�s necessaires
		$TempSource = new $Type();
		$TempSource->initFromId($Id);
		$TempSource->initChildTree();
		return $TempSource->getGroupe($Id);
	}

	function loadSchema() {
		//Si il n est pas charg�alors on le charge sinon retour
		if (!$this->SchemaLoaded) {

			if (SCHEMA_CACHE){
				/*Charge le cache des modules, ou si il n'est pas disponible, va chercher le xml*/
				$CacheO = "Modules/".$this->Nom."/.Db.cache";
				$Class = "Class/DataBase/DbAnalyzer.class.php";
				if (file_exists($CacheO) && (filemtime($CacheO) >= filemtime($Schema)) && (filemtime($CacheO) >= filemtime($Class))&&SCHEMA_CACHE) {
					$Cache = file_get_contents($CacheO);
					$GLOBALS["Chrono"]->start("MODULE LOAD ".$this->Nom);
					$this->Db = unserialize($Cache);
					$GLOBALS["Chrono"]->stop("MODULE LOAD ".$this->Nom);
				}
			}
			if (!is_object($this->Db)){
				$this->Db = new DbAnalyzer($this->Schema,$this->Nom);
				if (SCHEMA_CACHE) {
					$CacheO = "Modules/".$this->Nom."/.Db.cache";
					$Class = "Class/DataBase/DbAnalyzer.class.php";
					$ContentCache = serialize($this->Db);
					$File = fopen($CacheO,"w");
					fwrite($File,$ContentCache);
					fclose($File);
				}
			}
			$this->Db->setCache($this->Cache);
			$this->SchemaLoaded = true;
			if (!empty($this->TriggerFile) && file_exists($this->TriggerFile)){
				$XmlContent = new xml2array($this->TriggerFile);
				$XmlResult=$XmlContent->getResult();
				$XmlResult=$XmlResult["ACTIONS"]["#"]["ACTION"];
				foreach($XmlResult as $Action){
					$T = new Trigger($Action,$this->Nom);
					$this->Triggers[] = $T;
				}
			}

			return false;
		}
		//Si il y a une source de donnée alternative alors on la charge
		if (is_array($this->Bdd)&&sizeof($this->Bdd)){
			foreach ($this->Bdd as $k=>$b) {
				if (empty($GLOBALS["Systeme"]->Db[$k]))switch ($b["TYPE"]){
					case "mysql":
						require_once "Class/Lib/MDB2.php";
						$GLOBALS["Systeme"]->Db[$k] = & MDB2::connect($b["DSN"]);
						$GLOBALS["Systeme"]->Db[$k]->options["portability"]=0;
						$GLOBALS["Systeme"]->Db[$k]->setFetchMode(MDB2_FETCHMODE_ASSOC);
						$GLOBALS["Systeme"]->Db[$k]->exec("SET NAMES 'utf8';");
					break;
					case "ldap":
						$server=$b["HOST"];
						$admin=$b["USERNAME"];
						$passwd=$b["PASS"];
						$GLOBALS["Systeme"]->Db[$k] = ldap_connect($server);  // assuming the LDAP server is on this host
						if ($GLOBALS["Systeme"]->Db[$k]) {
							ldap_set_option($GLOBALS["Systeme"]->Db[$k], LDAP_OPT_PROTOCOL_VERSION, 3);
							// bind with appropriate dn to give update access
							$r=ldap_bind($GLOBALS["Systeme"]->Db[$k], $admin, $passwd);
							if(!$r) die("ldap_bind failed<br>");
// 							echo "ldap_bind success";
							//ldap_close($GLOBALS["Systeme"]->Db[$k]);
						} else {
// 							echo "Unable to connect to LDAP server";
						}
					break;
				}
			}
		}
	}

	function isInterface($ObjectClass,$Interface) {
		return (!$this->getInterface($ObjectClass,$Interface))?false:true;
	}
	function getInterface($ObjectClass,$Interface) {
		if (SHARED_SKIN==""&&$GLOBALS["Systeme"]->Skin=="")return false;
		//SKin partagée
		$Chemin="Skins/".SHARED_SKIN."/Modules/".$this->Nom;
		if (!file_exists($Chemin)) $Chemin="Skins/".SHARED_SKIN."/Modules/Default";
		//Skin en cours
		$SkinChemin="Skins/".$GLOBALS["Systeme"]->Skin."/Modules/".$this->Nom;
		if (!file_exists($SkinChemin)) $SkinChemin="Skins/".$GLOBALS["Systeme"]->Skin."/Modules/Default";
		if (DEBUG_MODULE)echo "***IS INTERFACE $ObjectClass | $Interface => ";
		//Cas ObjectClass + Interface fichier
		if ($Interface!="Default")$CheSkinTest = $SkinChemin."/".$ObjectClass.(($ObjectClass!=""&&$Interface!="")?"/":"").$Interface.".md";
		if ((file_exists($CheSkinTest))){
			if (DEBUG_MODULE)echo $CheSkinTest."\r\n";
			return $CheSkinTest;
		}
		//Cas Objectclass + interface dossier
		$CheFoldSkinTest = $SkinChemin."/".$ObjectClass.(($ObjectClass!=""&&$Interface!="")?"/":"").$Interface."/Default.md";
		if ((file_exists($CheFoldSkinTest))){
			if (DEBUG_MODULE)echo $CheFoldSkinTest."\r\n";
			return $CheFoldSkinTest;
		}
		//Cas ObjectClass Default et interface dossier
                $CheSkinDefaultFoldTest = $SkinChemin."/Default".(($Interface!="")?"/":"").$Interface."/Default.md";
		if ((file_exists($CheSkinDefaultFoldTest))){
			if (DEBUG_MODULE)echo $CheSkinDefaultFoldTest."\r\n";
			return $CheSkinDefaultFoldTest;
		}
		//Cas ObjectClass Default et interface fichier
                $CheSkinDefaultTest = $SkinChemin."/Default".(($Interface!="")?"/":"").$Interface.".md"; 
		if ((file_exists($CheSkinDefaultTest))){
			if (DEBUG_MODULE)echo $CheSkinDefaultTest."\r\n";
			return $CheSkinDefaultTest;
		}
		//Cas Objectclass + interface fichier + skin partage
		$CheTest = $Chemin."/".$ObjectClass.(($ObjectClass!=""&&$Interface!="")?"/":"").$Interface.".md";
		if ((file_exists($CheTest))){
			if (DEBUG_MODULE)echo $CheTest."\r\n";
			return $CheTest;
		}
		//Cas Objectclass + interface dossier + skin partage
		$CheFoldTest = $Chemin."/".$ObjectClass.(($ObjectClass!=""&&$Interface!="")?"/":"").$Interface."/Default.md";
		if ((file_exists($CheFoldTest))){
			if (DEBUG_MODULE)echo $CheFoldTest."\r\n";
			return $CheFoldTest;
		}
		//Cas ObjectClass Default et interface dossier + skin partage
                $CheDefaultFoldTest = $Chemin."/Default".(($Interface!="")?"/":"").$Interface."/Default.md";
		if ((file_exists($CheDefaultFoldTest))){
			if (DEBUG_MODULE)echo $CheDefaultFoldTest."\r\n";
			return $CheDefaultFoldTest;
		}
		//Cas ObjectClass Default et interface fichier + skin partage
                $CheDefaultTest = $Chemin."/Default".(($Interface!="")?"/":"").$Interface.".md";
		if ((file_exists($CheDefaultTest))){
			if (DEBUG_MODULE)echo $CheDefaultTest."\r\n";
			return $CheDefaultTest;
		}
		if (DEBUG_MODULE)echo " FALSE \r\n";
		return false;
	}

	function Update(){
		$this->loadSchema();
		for ($i=0;$i<count($this->Db->ObjectClass);$i++){
			$Drv = $this->Db->ObjectClass[$i]->Conf["CRONUPDATE"];
			if (!empty($Drv)){
				$this->Db->ObjectClass[$i]->checkNew($Drv);
			}
		}
	}
	function getByTitleOrFkey($Element){
		$Obj=-1;
		$t = sizeof($this->Schema["OBJECTCLASS"]);
		for ($i=0; $i<$t; $i++){
			if ($Element == $this->Schema["OBJECTCLASS"][$i]["@"]["title"]) $Obj=$i;
		}
		if ($Obj!=-1) return Array("Type"=>1,"Nom"=>$Element,"Num"=>$Obj);
		for ($i=0;$i<$t;$i++){
			if (is_array($this->Schema["OBJECTCLASS"][$i]["#"]["FKEY"]))foreach($this->Schema["OBJECTCLASS"][$i]["#"]["FKEY"] as $E){
				$Y = explode(",",$E["@"]["data"]);
				if ($Element==$Y[0]) return Array("Type"=>2,"Nom"=>$E["#"]);
			}
		}
		return Array("Type"=>-1,"Nom"=>"");
	}
	function isReflexive($Element){
		$Obj=-1;
		$t = sizeof($this->Schema["OBJECTCLASS"]);
		for ($i=0;$i<$t;$i++){
			if ($Element == $this->Schema["OBJECTCLASS"][$i]["@"]["title"]){
				if (is_array($this->Schema["OBJECTCLASS"][$i]["#"]["FKEY"]))foreach($this->Schema["OBJECTCLASS"][$i]["#"]["FKEY"] as $E){
					$Y = explode(",",$E["@"]["data"]);
					if ($Element==$Y[0]) return true;
				}else return false;
			}
		}
		return false;
	}

	function loadInterface($Lien,$NewSkin=0,$DefaultTry=false) {
		if (DEBUG_MODULE)echo (($DefaultTry)?"=- ":"").(($NewSkin)?"=- ":"")."=- LOAD INTERFACE $Lien | ".(($NewSkin)?"ALTERSKIN":"")."\r\n";
		$CheTest =$Lien;

		if (DEBUG_MODULE)echo (($DefaultTry)?"=- ":"").(($NewSkin)?"=- ":"")."=- TEST =>  $CheTest | ".$this->getInterface("",$CheTest)."\r\n";
		//////////////////////////////////////////////////////////////
		$Chemin = $CheTest;
		if ($t=$this->getInterface("",$Chemin)) {
			$Chemin = $t;
			if (DEBUG_MODULE)echo (($DefaultTry)?"=- ":"").(($NewSkin)?"=- ":"")."PASS =>  $t \r\n";
			$GLOBALS["Systeme"]->Log->log("LOAD MODULE =>> $Chemin");
 			$Data=@file_get_contents($t);
		}else
		{
			//Test avec un dossier en default
			$T = explode("/",$Lien);
			$CheDef = "Default";
			for($i=1;$i<sizeof($T);$i++) $CheDef .= "/" . $T[$i];
			if ($t=$this->getInterface("",$CheDef)){
				if (DEBUG_MODULE)echo (($DefaultTryfile_exists)?"=- ":"").(($NewSkin)?"=- ":"")."DEFAULT PATH =>  $t \r\n";
				$GLOBALS["Systeme"]->Log->log("LOAD MODULE DEFAUT PATH =>> $t");
				$Data=@file_get_contents($t);
			}else {
				$LastWorking = $this->getInterface("","Default/".$T[sizeof($T)-1]);
				for($i=2;$i<sizeof($T);$i++) $CheDef .= "/" . $T[$i];
				if (DEBUG_MODULE)echo (($DefaultTryfile_exists)?"=- ":"").(($NewSkin)?"=- ":"")."LASTWORKING =>  $LastWorking \r\n";
				$GLOBALS["Systeme"]->Log->log("LOAD MODULE LASTWORKING =>> $LastWorking");
				$Data=@file_get_contents($LastWorking);
			}
		}
		$Process = new Process();
		$Bloc=new Bloc();
		$Bloc->loadData($Data);
		$Bloc->init($Process);
		$Bloc->Path = $Path;
		return $Bloc;
	}

	function checkIfModified($URLINFO){
		//RENVOIE VRAI SI MODIFICATON OU NON ACCES, FAUX SINON
		if (!file_exists($URLINFO)) return 1;
		$Content=file($URLINFO);
		for ($i=0;$i<count($Content);$i++){
			$Ligne=rtrim($Content[$i]);
			$TabLigne=explode("||",$Ligne);
			//echo "new:".filemtime($TabLigne[0]),"orig:".$TabLigne[1],"<br>";
			if(@filemtime($TabLigne[0])>$TabLigne[1]) return 1;
		}
		return 0;
	}

	function splitQuery($Lien) {
     		if (DEBUG_MODULE)echo "=- SPLIT QUERY ".$this->Nom." | ".$Lien."\r\n";
		$Lien=str_replace($this->Nom."/","",$Lien);
		$Out=split("/",$Lien);
		$p="";
		//La premiere occurence n'est pas une datasource
		$this->loadSchema();
		$t = $this->Db->getDefaultObjectClass();
		if ($t&&$t!=$Out[0]){
			//soit il existe une data source par défaut
			for ($i=0;$i<sizeof($Out);$i++) $p .=(($i>0&&$Out[$i]!=""&&$p!="")?"/":"").$Out[$i];
			if (DEBUG_MODULE)echo "CAS DEFAULT => ".print_r($t,true)." $p\r\n";
			if ($this->isInterface($t,$p)){
				$Interface = Array(
					"DataSource"=>$t,
					"Interface"=>$p
				);
			}
			//On insere l'objectclass par defaut au bon endroit pour reconstituer la requete
			$Out2[0] = $t;
			if ($Out[0]!="")for ($i=0;$i<sizeof($Out);$i++) $Out2[$i+1] = $Out[$i];
			$Out = $Out2;
		}else 
		//Le cas ou le lien est vide
		if ($Lien==""){
			$Result[0]["Type"] = "Interface";
			$Result[0]["Query"] = "";
			$Result[0]["Interface"] = "";
			return $Result;
		}
		//On teste la premiere occurence
		$Object = $this->getByTitleOrFkey($Out[0]);
		if ($Object["Type"]==-1) {
			//soit il s'agit d'un appel d'interface
			if (DEBUG_MODULE)echo "CAS INTERFACE => ".print_r($Object,true)." $p\r\n";
			for ($i=1;$i<sizeof($Out);$i++) $p .=(($i>1&&$Out[$i])?"/":"").$Out[$i];
			if ($this->isInterface($Out[0],$p)){
				$TypeObjet = "Interface";
				$Result[0]["Type"] = "Interface";
				$Result[0]["Interface"] = Array(
					"DataSource"=>"",
					"Interface"=>$Out[0].(($Out[0]!=""&&$p!="")?"/":"").$p
				);
			}
			//Sinon erreur
			if ($TypeObjet==""){
				$Result[0]["Type"] = "Erreur";
			}
		}else $TypeObjet = "DataSource";
		if ($TypeObjet=="DataSource"){
			//La premiere occurence est une datasource
			for ($i=0;$i<sizeof($Out);$i++) {
				$Object = $this->getByTitleOrFkey($Out[$i]);
				if ($Object["Type"]!=-1) {
					if ($Last>-1) {
						//on Genere la donn� (Ds/Value/Ds/Value)
						for ($j=$Last+1;$j<$i;$j++) {
							$Temp=$Out[$j];
							//echo $Out[$Last]."-".$Object[0].$Object[1]."\r\n";
							$Tab['DataSource'] = $LastName;
							$Tab['Key'] = $LastKey;
							$Tab['Value'] = $Temp;
							$Result[] = $Tab;
						}
						//Le cas ou on fait une requete parent (Ds/Ds/Value)
						if ($Last==$i-1) {
							$Tab['DataSource'] = $LastName;
							$Tab['Value'] = "";
							$Tab['Key'] = $LastKey;
							$Result[] = $Tab;
						}
					}
					$Last=$i;
					$LastName = $Object["Nom"];
					$LastKey = $Object["Fkey"];
					unset($Tab);
				}
			}
			//echo "\r\n-\r\n";
	/*		print_r($Result);
			echo "Valeur i $i Last $Last \r\n";*/
			//On extrait l interface de la derniere occurence
			if (($Last>-1)&&($Last!=$i-1)) {
				//on Genere la donn�e
				for ($j=$Last+1;$j<$i;$j++) {
					if ($j==$i-1) {
						//On teste il y a plusieurs occurence depuis la derniere ObjectClass trouve
						if ($Last+1<$i-1) {
							//Donc l interface concerne le dernier ObjectClass trouve
	// 						echo $Lien."--> Recherche Directe Absolue- ".$Out[$Last]."\r\n";
							$Obj = $Out[$Last];
						}else{
							//On teste si il y a au moins une occurence
							if (count($Result)>0) {
								//Donc l interface concerne l objectclass precedent le dernier
								if ($Result[count($Result)-2]['Value']!=""&&$Result[count($Result)-2]['Value']!="*"){
									if ($Out[$Last+1]!=""){
										if ($Out[$Last+1]=="*") $Type="Recursiv";
										else $Type="Direct";
	//   									echo $Lien."--> Recherche Directe Absolue- ".$Out[$Last]." - ".$Out[$Last+1]."\r\n";
									}else{
										$Type="Child";
	// 									echo $Lien."--> Recherche Enfant Absolue- ".$Out[$Last]."\r\n";
									}
								}else{
									if ((sizeof($Result)==1&&$Result[0]['Value']=="")||($Result[0]['Value']=="*"&&sizeof($Result)==2)) {
										//Verification
	// 									if (sizeof($Out)>3) {
	// 										//ERREUR
	// 										$Type="Erreur";
	// 									}else{
	
											$Type="Parent";
	// 									}
	// 									echo $Lien."--> Recherche Parent - ".$Out[$Last]."\r\n";
									}else{
										if ($Out[$Last+1]=="*") $Type="Recursiv";
										elseif($Out[$Last+1]=="") $Type="Child";
										else $Type="Direct";
	//  									echo $Lien."--> Recherche Directe Absolue- ".$Out[$Last]." - ".$Out[$Last+1]."\r\n";
									}
								}
								$Obj = $Result[count($Result)-1]['DataSource']."/".$Out[$Last];
							}else{
								//Donc l interface concerne le dernier ObjectClass trouve
								if ($Out[$Last+1]!=""){
									if ($Out[$Last+1]=="*"){
										$Type="Recursiv";
	// 									echo $Lien."--> Recherche Recursiv Simple(&|) - ".$Out[$Last]."\r\n";
									}else{
										$Type="Direct";
	// 									echo $Lien."--> Recherche Directe Simple(&|)Relative|Multi-search - ".$Out[$Last]."\r\n";
									}
								}else{
									$Type="Child";
	// 								echo $Lien."--> Recherche Enfant - ".$Out[$Last]."\r\n";
								}
								$Obj = $Out[$Last];
							}
						}
						//On teste si le dernier parametre est une interface
						if ($this->isInterface($Obj,$Out[$j])||$this->isInterface($Out[$Last],$Out[$j])) {
							//Si c'est une interface alors ce n est pas une requete
							$O = (($this->isInterface($Obj,$Out[$j]))?$Obj:$Out[$Last]);
/*							print_r($Out);
							echo "IS INTERFACE $O ".$Out[$j]."\r\n";*/
							$Type="Interface";
							$Interface['DataSource']=$O;
							$Interface['Interface']=$Out[$j];
							if (sizeof($Out)-1==$j&&$j-$Last<2){
								$Tab['DataSource'] = $Out[$Last];
								$Result[] = $Tab;
							}
						}else{
							$Temp=$Out[$j];
							$Tab['DataSource'] = $Out[$Last];
							$Tab['Value'] = $Temp;
							if (is_array($Result)||empty($Result))$Result[] = $Tab;
						}
					}else{
						$Temp=$Out[$j];
						$Tab['DataSource'] = $Out[$Last];
						$Tab['Value'] = $Temp;
						$Result[] = $Tab;
					}
				}
	/*			if (count($Interface)>1) {
					$Result[] = $Interface;
				}*/
			}else{
				//Verification de la syntaxe de la requete il ne faut pas que les deux dernieres occurences soient des datasources
				if ($Out[$Last]!=$Out[$Last-1]){
	// 				echo $Lien."--> CHECK SYNTAXE FORCE CHILD - ".$Out[$Last]."\r\n";
					$Type="Child";
					$Tab['DataSource'] = $Out[$Last];
					$Tab['Value'] = "";
					$Result[] = $Tab;
				}else{
					$Type="Erreur";
				}
			}
			if ($Type=="Direct"||$Type=="Child") {
				//Verifions qu il ne s agit pas d une multisearch
				if (preg_match("#[\<\>\!\=\~]{1,2}#",$Out[$Last+1])) {
					$Type="Multi";
				}
			}
			//On genere la valeur de la query
			$Query=$this->Nom;
			for ($f=0;$f<sizeof($Out)-1;$f++) {
				$Query .= "/".$Out[$f];
			}
			if ($Type!="Interface") $Query.= "/".$Out[sizeof($Out)-1];
			$Result[0]["Type"] = $Type;
			$Result[0]["Query"] = $Query;
			$Result[0]["Interface"] = $Interface;
		}
		if (DEBUG_MODULE)print_r($Result);
		return $Result;
	}
	//Appel depuis storproc pour lexecution de requete
	function callData($Query,$recurs="",$Ofst="",$Limit="",$OrderType="",$OrderVar="",$Selection="",$GroupBy=""){
		if (DEBUG_MODULE)echo "CALLDATA $Query \r\n";
		//On charge le Schema
		$this->loadSchema();
		//$GLOBALS["Chrono"]->start("MODULE splitQuery");
 		$TabQuery = $this->splitQuery($Query);
/* 		if ($this->Nom=="Explorateur")echo "-------------------------------------------------\r\n";
 		if ($this->Nom=="Explorateur")print_r($TabQuery);*/
		//$GLOBALS["Chrono"]->stop("MODULE splitQuery");
		//On met la verification des droits a faux.
		//$this->Db->checkRightsSuccess = true;
		//sprint_r($TabQuery);
		if ($TabQuery[0]["Type"]=="Erreur") return ;
// 		$GLOBALS["Chrono"]->start("CALL DATA ".$Query);
		$Tab =  $this->Db->searchObject($TabQuery,$recurs,$Ofst,$Limit,$Query,$OrderType,$OrderVar,$Selection,$GroupBy);
// 		$GLOBALS["Chrono"]->stop("CALL DATA ".$Query);
// 		if ($this->Nom!="Explorateur"&&is_array($Tab[0]))print_r($Tab);
		//On ajoute les informations de la requete
		for ($i=0;$i<sizeof($Tab);$i++) {
			if (sizeof($Tab[$i]))$Tab[$i]["QueryType"] = $TabQuery[0]["Type"];
			if (sizeof($Tab[$i]))$Tab[$i]["Query"] = $TabQuery[0]["Query"];
			if (sizeof($Tab[$i]))$Tab[$i]["Module"] = $this->Nom;
		}
		return $Tab;
	}


	//Appel depuis la balise module pour affichage interface
	function setData($Lien,$recurs=0) {
 		if (DEBUG_MODULE){
			echo "***************************************\r\n";
			echo "** SET DATA $Lien"."		  \r\n";
		}
// 		$GLOBALS["Systeme"]->Log->log("SET DATA =>> $Lien");
		//On charge le Schema
		$this->loadSchema();
		//Analyse de l Url
		$Tab = $this->splitQuery($Lien);
		//On genere le lien de l interface
		if ($Tab[0]["Interface"]["DataSource"]=="")$DataSource = $Tab[sizeof($Tab)-1]["DataSource"]; else $DataSource = $Tab[0]["Interface"]["DataSource"];
		$Interface=$DataSource.(($DataSource!=""&&$Tab[0]["Interface"]["Interface"]!="")?"/":"").$Tab[0]["Interface"]["Interface"];
		//On appelle l interface concernee
		if ($Type=="Erreur") return ;
		//CHARGEMENT DU CACHE
		$Lien2 = str_replace("/","_",$Interface);
		$Lien2 = str_replace("__","_",$Lien2);
		if ($Lien2=="") $Lien2 = "Default";
		$URL = "Home/".$GLOBALS['Systeme']->User->Id."/.cache/".$Lien2.'.modCache';
		$URLCACHE = "Home/".$GLOBALS['Systeme']->User->Id."/.cache/";
		$FILENAME = $Lien2.'.modCache';
		$URLINFO = "Home/".$GLOBALS['Systeme']->User->Id."/.cache/".$Lien2.'.modInfo';
		$FILENAMEINFO = $Lien2.'.modInfo';
		if ((!file_exists($URLCACHE))||(!MODULE_CACHE)||$this->checkIfModified($URLINFO)){
			//On enregistre le fichier
			$Bloc=$this->loadInterface($Interface);
			if (MODULE_CACHE) {
				$GLOBALS["Systeme"]->Log->Log("-=>WRITE MODULE CACHE ".$URL);
				$ModulesLoaded = $Bloc->getModulesLoaded();
				$ModulesLoaded[] = $Path;
				$this->writeCacheFile(serialize($Bloc),$URLCACHE,$FILENAME);
				$Entree ="";
				foreach ($ModulesLoaded as $Key){
					$Entree.= $Key.'||';
					$Entree.=@filemtime($Key);
					$Entree.="\n";
				}
				$this->writeCacheFile($Entree,$URLCACHE,$FILENAMEINFO);
			}
		}else{
			if (!empty($this->QuickCache[$URL])){
				$Bloc = unserialize($this->QuickCache[$URL]);
			}else{
				$Bloc = file_get_contents($URL);
				$Bloc = unserialize($Bloc);
				$this->QuickCache[$URL] = serialize($Bloc);
				$GLOBALS["Systeme"]->Log->Log("LOAD MODULE FROM CACHE ".$URL);
			}
		}
// 		$Bloc->Conf = $Conf;
 		if (DEBUG_MODULE){
			echo "=>>>>>>$Type | $Interface\r\n";
			echo "***************************************\r\n";
		}
		return $Bloc;
	}

	function Query($Prefix,$Class,$Action) {
		$this->loadSchema();
		if ($Action=="AH"){
		//Ajout d'heritage
			$Vars=Process::ProcessQuery("Heritage_");
			$Entree["But"] = "Add_heritage";
			$Entree["Parent"] = $Vars["ObjectType"];
			for ($i=0;$i<10;$i++){
				if (array_key_exists("Enfant_$i",$Vars)){
					$Entree["Enfant"][] = $Vars["Enfant_$i"];
				}
			}
			$Entree["NomPropriete"] = $Vars["NomPropriete"];
			$Entree["TypePropriete"] = $Vars["TypePropriete"];
			$Entree["Description"] = $Vars["DescPropriete"];
			$Entree["Id"] = $Vars["Id"];
			$this->Db->Query($Entree);
		}
		if ($Action=="M"){
		//Modification d'objet
			$Generic = new genericClass($this->Nom);
			$Generic->initFromId($GLOBALS["Systeme"]->PostVars["FormSys_Identifiant"],$Class);
			$Generic->Update = 1;
			$Generic->saveChanges();
		}
		if ($Action=="A"){
		//Ajout d'objet
			$Generic = new genericClass($this->Nom);
			$Generic->initFromType($Class);
			$Generic->saveChanges();
		}
		if ($Action=="AJ"){
		//Ajout d'association
			$Generic = new genericClass($this->Nom);
			$IdEnfant = $GLOBALS["Systeme"]->PostVars["Form_Objet"];
			$IdParent = $GLOBALS["Systeme"]->PostVars["Form_ParentId"];
			$ObjParent = $GLOBALS["Systeme"]->PostVars["Form_ObjectParent"];
			$Generic->initFromId($IdEnfant,$Class);
			$Generic->addFkey($ObjParent,$IdParent);
			$Generic->Save();
		}
		if ($Action=="S"){
		//Suppression
			$Id = $GLOBALS["Systeme"]->PostVars["Form_Id"];
			$ObjectType = $GLOBALS["Systeme"]->PostVars["Form_ObjectType"];
			if ($GLOBALS["Systeme"]->PostVars["Form_Delete"]=="Obj"){
			//d'un objet
				$Generic = new genericClass($this->Nom);
				$Generic->initFromQuery($GLOBALS["Systeme"]->PostVars["Form_Query"]);
				$Old = $Generic->Historique[count($Generic->Historique)-1];
				$GLOBALS["Systeme"]->registerVar("oldId",$Old["Id"]);
				$GLOBALS["Systeme"]->registerVar("oldObj",$Old["ObjectType"]);
				$Generic->setDelete();

			}elseif ($GLOBALS["Systeme"]->PostVars["Form_Delete"]=="Assoc"){
			//d'une association
				$Id =  $GLOBALS["Systeme"]->PostVars["FormSys_Objet"];
				$Generic = new genericClass($this->Nom);
				$Generic->initFromId($Id,$Class);
				$Old = explode("/",$GLOBALS["Systeme"]->PostVars["Form_ObjetSuppr"]);
				$Generic->deleteFKey($Old[0],$Old[1]);
				$Generic->Save();
			}
		}

	}

	function saveData($ObjTemp) {
//		print_r($ObjTemp);
	}
	
	function getTriggers($T="") {
		if (!$T)return $this->Triggers;
		else {
			if (is_array($this->Triggers)) foreach ($this->Triggers as $Tr) if ($Tr->Name==$T) return $Tr;
		}
	}
}



?>
